﻿// ====================================================================================================================
// Project: Camstar InSiteExtractor
// Source File: InSiteExtractor.cs
// Author: Roop Sin LE
// Created(MM/DD/YYYY HH:MM): 08/13/2010 9:14:21 PM
// Copyright: Camstar Inc.
// ====================================================================================================================

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Text;
using InSiteExtractor.Configuration;
using InSiteExtractor.Data;
using log4net;
using log4net.Config;

namespace InSiteExtractor
{
    internal class Program
    {
        // Define a static logger variable so that it references the
        private static readonly ILog Log = LogManager.GetLogger(typeof(Program));

        private static string _source;
        private static bool _generateSqlScript;
        private static bool _exportToText = false;
        private static Dictionary<string, string> _filterCsv = new Dictionary<string, string>();
        private static string _sheetName;
        

        /// <summary>
        /// Many Entry of the program
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            // Configure Log4Net
            XmlConfigurator.Configure();

            int argumentsCount = InitializeParameters(args);

            if (argumentsCount < 0 && _source == null || argumentsCount < 1 || argumentsCount > (args.Length - 1))
            {
                Usage();
            }

            try
            {
                //===========================================================================
                string envInfo = "(1) ------------- System Information --------------\n" +
                                 string.Format("\t CurrentDirectory = {0}\n", Environment.CurrentDirectory) +
                                 string.Format("\t MachineName      = {0}\n", Environment.MachineName) +
                                 string.Format("\t UserDomainName   = {0}\n", Environment.UserDomainName) +
                                 string.Format("\t UserName         = {0}\n", Environment.UserName) +
                                 string.Format("\t App Version      = {0}\n",
                                               Assembly.GetExecutingAssembly().GetName().Version) +
                                 string.Format("\t WorkingSet       = {0}\n", Environment.WorkingSet);

                Log.Info(envInfo);

                // Excel Files/Folder Input
                string excelFolder = args[argumentsCount++];
                // SQL Files Input
                string sqlFullPath = Path.Combine(Environment.CurrentDirectory, _source);
                string sqlFolder = Path.GetDirectoryName(sqlFullPath);

                string inputInfo = "(2) INPUT Information\n" +
                                   string.Format("\t SQL Scripts Path  = {0}\n", sqlFullPath) +
                                   string.Format("\t Excel Path        = {0}\n", excelFolder) +
                                   "-----------------------------------------------";
                Log.Info(inputInfo);


                InSiteDataExtractorManager logAnalyzerManager = InSiteDataExtractorManager.Instance();
                logAnalyzerManager.Initialize();

                Log.Info("Start processing ..............");
                if (_exportToText)
                {
                    Log.Info("Process Export to Text Mode!");
                    // Expect writing to a file
                    logAnalyzerManager.Write2Text(sqlFullPath, excelFolder);
                }
                else if (_generateSqlScript) // Generate SQL Script
                {
                    Log.Info("Process Generating SQL Script Mode!");
                    logAnalyzerManager.GenerateSqlScript(excelFolder, _sheetName, sqlFolder);
                }
                else // Extract Data
                {
                    Log.Info("Process Generating Extract Data Mode!");
                    
                    var dir = new DirectoryInfo(sqlFolder);
                    string searchCriteria = Path.GetFileName(sqlFullPath);
                    FileInfo[] files = dir.GetFiles(searchCriteria);
                    if (files.Length > 0)
                    {
                        logAnalyzerManager.ExtractData(files, excelFolder, _filterCsv);
                    }
                    else
                    {
                        Log.ErrorFormat("No SQL Script is matched. Please verify your input parameters! ");
                    }

                } 
            }
            catch (Exception mex)
            {
                Log.Error("Error occured during initializing. Please check the error :" + mex.Message);
            }

            Log.Info("Processed successfull!");
            //Console.ReadKey();
        }



        /// <summary>
        /// Print out command line usage.
        /// </summary>
        private static void Usage()
        {
            Console.Out.WriteLine("The tool to extract data from Database and update data into Excel files");
            Console.Out.WriteLine();
            Console.Out.WriteLine("Usage: InSiteExtractor -source SqlScriptPath [-F key1=filterCSV1] [-F key2=filterCSV2] [-G] excelPath");
            Console.Out.WriteLine();
            Console.Out.WriteLine("source       Specifies SQL Script file(s) used to extract data from Database.");
            Console.Out.WriteLine("excelPath    Specifies the folder consists  of Excel to update.");
            Console.Out.WriteLine("-F           Indicate a pair key & SCV file for filtering. $key$ must be defined in SQL");
            Console.Out.WriteLine("-G           Generate SQL Scripts name based on Excels.");
            Console.Out.WriteLine();
            Console.Out.WriteLine(@"Ex: InSiteExtractor -source Scripts\*.sql ""Excel Files""");
            Console.Out.WriteLine(@"        -> Used for extracting data");
            Console.Out.WriteLine(@"    InSiteExtractor -source Scripts\*.sql -F ProductName=Product.csv ""Excel Files""");
            Console.Out.WriteLine(@"    InSiteExtractor -source Scripts\*Fact*.sql -F Key1=Factory.csv -F Key2=List2.csv ""Excel Files""");
            Console.Out.WriteLine(@"        -> Used for extracting data with product filtering");
            Console.Out.WriteLine(@"    InSiteExtractor -source ScriptsTemplates\*.sql -G ""Excel Files""");
            Console.Out.WriteLine(@"    InSiteExtractor -source ScriptsTemplates\*.sql -G ""Excel Files\*Product*""");
            Console.Out.WriteLine(@"        -> Used for generating SQL Script Template from all excels in the folder ");
            Console.Out.WriteLine();

            Environment.Exit(1);
        }

        /// <summary>
        /// Parser input parameters
        /// </summary>
        /// <param name="arguments">Indicate input parameters for User entering</param>
        /// <returns>Last index for paramters (-XXXX)</returns>
        private static int InitializeParameters(string[] arguments)
        {
            int i = 0;
            int requriedParaNo = 1;
            while (i < arguments.Length - requriedParaNo && arguments[i].StartsWith("-"))
            {
                if (arguments[i].Equals("-source"))
                {
                    _source = arguments[i + 1];
                    i += 2;
                }
                else if (arguments[i].Equals("-S")) // Hidden
                {
                    _sheetName = arguments[i + 1];
                    i += 2;
                }
                else if (arguments[i].Equals("-F")) // Optional
                {
                    string pair = arguments[i + 1];
                    string[] items = pair.Split('=');
                    if (items.Length == 2 && !_filterCsv.ContainsKey(items[0]))
                    {
                        _filterCsv[items[0]] = items[1];
                        requriedParaNo += 1;
                        i += 2;
                    }
                    else
                    {
                        i = -1; // Error case
                        break;
                    }
                }
                else if (arguments[i].Equals("-G")) // Optional
                {
                    _generateSqlScript = true;
                    i += 1;
                }
                else if (arguments[i].Equals("-E")) // Export to a file (Not support to User)
                {
                    _exportToText = true;
                    i += 1;
                }
                else
                {
                    Usage();
                }
            }
            return i;
        }
    }
}